/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cubelabs.nexus.service;

import cubelabs.nexus.dao.OrganizationDAO;
import cubelabs.nexus.dao.OrganizationRequestDao;
import cubelabs.nexus.dao.UserDAO;
import cubelabs.nexus.domain.BaseResponse;
import cubelabs.nexus.domain.FileUploadResponseDTO;
import cubelabs.nexus.domain.NexusFileUpload;
import cubelabs.nexus.domain.OrganizationDetailsDto;
import cubelabs.nexus.domain.OrganizationDto;
import cubelabs.nexus.domain.OrganizationRequestDto;
import cubelabs.nexus.domain.UserDTO;
import cubelabs.nexus.entity.Organization;
import cubelabs.nexus.entity.OrganizationRequest;
import cubelabs.nexus.entity.User;
import cubelabs.nexus.utils.FileUploadUtils;
import cubelabs.nexus.utils.GenericUtils;
import cubelabs.nexus.utils.OrganizationUtil;

import java.text.ParseException;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author chaitanya
 */
@Service
public class OrganizationService {

    @Autowired
    private OrganizationDAO organizationDAO;
    @Autowired
    private UserDAO userDAO;
    @Autowired
    private OrganizationRequestDao organizationRequestDao;

    @Transactional
    public Organization createorUpdateOrganization(OrganizationDto organizationDto, User user) throws ParseException {
        //System.out.println(" creating organization with title:" + organization.getTitle() + " and by user :" + user.getId());
    	Organization organization = null;
    	if(organizationDto.getId() == null) {
    		organization = new Organization();
    	} else {
    		organization = organizationDAO.findById(organizationDto.getId(), false);
    	}
        
        organization.setTitle(organizationDto.getTitle());
        organization.setDescription(organizationDto.getDescription());
        organization.setUser(user);
        organization = organizationDAO.makePersistent(organization);
        return organization;
    }

    @Transactional
    public List<OrganizationDto> findOrganizationsByUser(User user) {
        try {
            List<Organization> list = organizationDAO.getMyOrganizations(user);
            return OrganizationUtil.getOrganizationDtos(list);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    
    @Transactional
	public FileUploadResponseDTO uploadOrgLogoToAmazon(NexusFileUpload nexusFileUpload, Long orgId) {
		FileUploadResponseDTO fileUploadResponseDTO = new FileUploadResponseDTO();
		try{
			Date date = new Date();
			String fileUrl = FileUploadUtils.uploadOrgLogoToAmazon(nexusFileUpload, String.valueOf(orgId), date.toString());
			String fileName = nexusFileUpload.getMultiPartFile().getOriginalFilename();
			Organization org = organizationDAO.findById(orgId, false);
			org.setLogopath(fileUrl);
			organizationDAO.makePersistent(org);
			
			fileUploadResponseDTO.setFileName(fileName);
			fileUploadResponseDTO.setFileUrl(fileUrl);
		}catch(Exception exception){
			exception.printStackTrace();
			throw new RuntimeException(exception);
		}

		return fileUploadResponseDTO;
	}
    
   

    @Transactional
    public BaseResponse inviteExpert(Long organizationId, Long userId, Long ownerId, String message) {
        if (ownerId == userId) {
            return new BaseResponse((short) -1, "inviting yourself");
        }
        Organization organization = organizationDAO.findById(organizationId, false);
        if (organization.getUser().getId() != ownerId) {
            return new BaseResponse((short) -1, "no permissio");
        }

        OrganizationRequest or = new OrganizationRequest();
        User user = userDAO.findById(userId, false);
        if (!user.isExpert) {
            return new BaseResponse((short) -1, "user not expert");
        }
        or.setUser(user);
        or.setOrganization(organization);
        or.setRequestedByUser(false);
        or.setMessage(message);
        organizationRequestDao.makeTransient(or);
        return new BaseResponse((short) 0, "Success");
    }

    @Transactional
    public BaseResponse joinOrganization(Long organizationId, Long userId, String message) {
        Organization organization = organizationDAO.findById(organizationId, false);
        if (userId == organization.getUser().getId()) {
            return new BaseResponse((short) -1, "you are already member");
        }
        OrganizationRequest or = new OrganizationRequest();
        User user = userDAO.findById(userId, false);
        or.setUser(user);
        or.setOrganization(organization);
        or.setRequestedByUser(true);
        or.setMessage(message);
        organizationRequestDao.makeTransient(or);
        return new BaseResponse((short) 0, "Success");
    }

    @Transactional
    public List<OrganizationRequestDto> getOrgRequests(Long userId) {
        List<OrganizationRequest> list = organizationRequestDao.getPendingRequests(userId);
        return (list == null) ? null : OrganizationUtil.getOrganizationRequests(list);
    }

    @Transactional
    public List<OrganizationRequestDto> getExpertRequests(Long ownerId, Long organizationId) {
        Organization organization = organizationDAO.findById(organizationId, false);
        if (organization.getUser().getId() != ownerId) {
            return null;
        }
        List<OrganizationRequest> list = organizationRequestDao.getRequestsFromExperts(organizationId);
        return (list == null) ? null : OrganizationUtil.getOrganizationRequests(list);
    }

    @Transactional
    public Boolean acceptExpertToJoin(Long orgRequestId,Long ownerId) {
        OrganizationRequest or = organizationRequestDao.findById(orgRequestId, false);
        if(or.getOrganization().getUser().getId()!=ownerId){
            return false;
        }
        or.setAccepted(Boolean.TRUE);
        organizationRequestDao.merge(or);
        return true;
    }

    @Transactional
    public Boolean acceptOrgnizationRequest(Long orgRequestId,long userId) {
         OrganizationRequest or = organizationRequestDao.findById(orgRequestId, false);
        if(or.getUser().getId()!=userId){
            return false;
        }
        or.setAccepted(Boolean.TRUE);
        organizationRequestDao.merge(or);
        return true;
    }

    @Transactional
    public OrganizationDetailsDto getOrganization(Long orgId) {
        Organization or=organizationDAO.findById(orgId,false);
        OrganizationDetailsDto odd = new OrganizationDetailsDto();
        if(or==null){
            odd.setResponseStatus((short)-1);
            odd.setErrorMessage("organization not present");
            return odd;
        }
        UserDTO userDTO=GenericUtils.getUserDTO(or.getUser());
        odd.setId(or.getId());
        odd.setTitle(or.getTitle());
        odd.setDescription(or.getDescription());
        odd.setOwner(userDTO);
        odd.setLogo(or.getLogopath());
        odd.setResponseStatus((short)0);
        return odd;
    }
    
    @Transactional
    public List<UserDTO> getExperts(long orgId){
        Organization or=organizationDAO.findById(orgId,false);
        if(or==null){
            return null;
        }
        List<User> users =organizationRequestDao.getExperts(orgId);
        return GenericUtils.getUserDTO(users);
    }
}
